package utils

import (
	"math"
	"time"
	"math/rand"
)

func Decimal(value float64) float64 {
	return math.Trunc(value*1e2+0.5) * 1e-2
}

//计算某个倍率, 一定经验值下龙鱼当前等级
func CalcLevel(curLevel, basicExp, curExp int64, multipleExp int64) int64 {
	var (
		nextExp float64
	)
	nextExp = (1 - pow(Decimal(float64(multipleExp)/float64(10)), int(curLevel))) / (1 - Decimal(float64(multipleExp)/float64(10))) * float64(basicExp)
	if curExp > int64(nextExp) {
		curLevel = curLevel + 1
	}
	return curLevel
}

//计算一定经验下的等级值
func CalcCurLevel(curLevel, basicExp, multipleExp, curExp int64) int64 {
	var (
		nextExp  float64
		newLevel int64
		i        int64
	)
	if curLevel < 15 {
		for i = 1; i <= 16; i++ {
			nextExp = (1 - pow(Decimal(float64(multipleExp)/float64(10)), int(i))) / (1 - Decimal(float64(multipleExp)/float64(10))) * float64(basicExp)
			if curExp < int64(nextExp) {
				newLevel = i
				break
			}
		}
	} else {
		for i = 1; i <= 16; i++ {
			nextExp = (1 - pow(Decimal(float64(multipleExp)/float64(10)), int(i))) / (1 - Decimal(float64(multipleExp)/float64(10))) * float64(basicExp)
			if curExp < int64(nextExp) {
				newLevel = i + 14
				break
			}
		}
	}

	return newLevel
}

//计算升级到下一级所需经验
func CalcNextLevelExp(curLevel, basicExp, multipleExp int64) int64 {
	var (
		nextExp float64
	)
	nextExp = (1 - pow(Decimal(float64(multipleExp)/float64(10)), int(curLevel))) / (1 - Decimal(float64(multipleExp)/float64(10))) * float64(basicExp)

	return int64(nextExp)
}

//计算两个等级之间按百分比得到的经验值
func PercentBetweenLevels(basicExp, curLevel, percent int64, multipleExp int64) int64 {
	var (
		nextExp float64
		val     float64
	)
	nextExp = (1 - pow(Decimal(float64(multipleExp)/float64(10)), int(curLevel+1))) / (1 - Decimal(float64(multipleExp)/float64(10))) * float64(basicExp)
	val = nextExp * Decimal(float64(percent)/float64(100))
	return int64(math.Ceil(val))
}

//计算到达某个等级所需要的经验值最小数值
func LevelInitExp(basicExp, curLevel int64, multipleExp int64) int64 {
	var (
		curExp float64
	)
	curExp = (1 - pow(Decimal(float64(multipleExp)/float64(10)), int(curLevel-1))) / (1 - Decimal(float64(multipleExp)/float64(10))) * float64(basicExp)
	return int64(curExp)
}

/*
	实现一个数的整数次方
	pow(x, n)
*/
func pow(x float64, n int) float64 {
	if x == 0 {
		return 0
	}
	result := calPow(x, n)
	if n < 0 {
		result = 1 / result
	}
	return result
}

func calPow(x float64, n int) float64 {
	if n == 0 {
		return 1
	}
	if n == 1 {
		return x
	}

	// 向右移动一位
	result := calPow(x, n>>1)
	result *= result

	// 如果n是奇数
	if n&1 == 1 {
		result *= x
	}

	return result
}

//计算一段时间内，鱼食可以恢复的数量
func RecoverFoodNum(recover, lastRecover int64) int64 {
	var (
		now   int64
		reNum float64
	)
	now = time.Now().Unix()
	reNum = math.Floor(Decimal(float64((now - lastRecover) / recover)))
	return int64(reNum)
}

//计算龙鱼离线奖励
func GetFishOfflineReward(logout, now, copper int64, rate float64) int64 {
	var (
		reCoins   int64
		perSecond int64 //每几秒计算一次
		minus     int64 //时间差值
	)
	perSecond = 1
	minus = now - logout
	if minus >= 86400 { //超过24小时按照24小时计算
		minus = 86400
		reCoins = minus / perSecond
	} else if minus > 600 { //超过10分钟开始计算离线收益
		reCoins = minus / perSecond
	}
	return int64(float64(reCoins) * rate)
}

//计算抽奖恢复次数
func GetLotteryNumber(lastTime int64) int64 {
	var (
		now  int64
		resp int64
	)
	now = time.Now().Unix()
	//每六小时恢复一次
	resp = (now - lastTime) / 86400
	return resp
}

//CalcRealFragment: 计算实际合成道具数量和碎片消耗量
func CalcRealFragment(price, num int64) (int64, int64) {
	var (
		prop, realFragment int64
	)
	prop = num / price
	realFragment = prop * price
	return prop, realFragment
}

//RandInt64: 生成范围随机数
func RandInt64(min, max int64) int64 {
	rand.Seed(time.Now().UnixNano())
	if min >= max || min == 0 || max == 0 {
		return max
	}
	return rand.Int63n(max-min) + min
}

//RandomInt64: 闭区间随机数
func RandomInt64(min, max int64) int64 {
	rand.Seed(time.Now().UnixNano())
	if min >= max {
		return max
	}
	return rand.Int63n(max-min) + min
}

//Rounded: 四舍五入
func Rounded(x float64) int64 {
	return int64(math.Floor(x + 0.5))
}
